
import jinja2

from email_template.imp import data_type
from email_template.imp import metadata_mimic
from email_template.imp import store_mimic


def GetEmailTemplate(key):
  """

  Args:
    key: str, The `key` identifier of the desired EmailTemplate.
  Return:
    EmailTemplate: dict, The retrieved EmailTemplate for the given "key".
  Exceptions:
    KeyError: No EmailTemplate found with the given "key".
    ValueError:  "key" is None.
  """
  #TODO(raulg): Add the validation
  if key is None:
    raise ValueError('key is None')

  template = store_mimic.GetTemplate(key)

  if template is None:
    raise KeyError('Template with key "%s", does not exist' % key)

  return template


def ListEmailTemplates():
  """

  Return:
    EmailTemplateAbstract  list<dict>, A list of EmailTemplateAbstract
      instances in dict representation.
  """
  return store_mimic.GetTemplates()


def CreateEmailTemplate(key, description, to, cc, subject, body):
  """

  Args:
    key: str, The key used to identify a given template.
    description:, str, A short description to aid user in identifying
      EmailTemplate usage.
    to: list<email_addresses>, Set of email addresses. Required.
    cc: list<email_addresses>, Set of email addresses. Optional.
    subject: str, The subject line to use for email deliveries.
    body: str, The body to use for email deliveries.
  Exceptions:
    ValueError:
      - "key" value not supplied.
      - "key" value beyond 16 char limit.
      - "key" value not alphanumeric, period, or dash only characters.
      - Duplicate `key`.
      - "description greater then 1024 characters.
      - "to" is None.
      - "to" set not greater than 0 length.
      - not all "to" set members are valid email addresses.
      - not all "cc" set members are valid email addresses.
      - "subject" not supplied.
      - "subject" greater than 1024 characters.
      - "body" not supplied.
  """
  template = data_type.EmailTemplate({
    'key': key,
    'description': description,
    'to': to,
    'cc': cc,
    'subject': subject,
    'body': body
  })

  metadata_mimic.Validate(template)

  store_mimic.CreateTemplate(template)


def UpdatedEmailTemplate(key, description, to, cc, subject, body):
  """

  Args:
    key: str, The key used to lookup a given template.
    description:, str, A short description to aid user in identifying
      EmailTemplate usage.
    to: list<email_addresses>, Set of email addresses. Required.
    cc: list<email_addresses>, Set of email addresses. Optional.
    subject: str, The subject line to use for email deliveries.
    body: str, The body to use for email deliveries.
  Exceptions:
    KeyError: EmailTemplate not found for given "key".
    ValueError:
      - "key" value not supplied.
      - "key" value beyond 16 char limit.
      - "key" value not alphanumeric, period, or dash only characters.
      - Duplicate `key`.
      - "description greater then 1024 characters.
      - "to" is None.
      - "to" set not greater than 0 length.
      - not all "to" set members are valid email addresses.
      - not all "cc" set members are valid email addresses.
      - "subject" not supplied.
      - "subject" greater than 1024 characters.
      - "body" not supplied.
  """
  #TODO(raulg): Add the validation
  if key is None:
    raise ValueError('key is None')

  template = data_type.EmailTemplate({
    'key': key,
    'description': description,
    'to': to,
    'cc': cc,
    'subject': subject,
    'body': body
  })

  store_mimic.UpdateTemplate(template)


def DeleteEmailTemplate(key):
  """

  Args:
    key: str, The key used to lookup a given template.
  Exceptions:
    KeyError: EmailTemplate not found for given "key" argument.
  """
  if key is None:
    raise ValueError('key is None')

  store_mimic.DeleteTemplate(key)


def ResolveTemplate(template, data):
  """

  Args:
    template: str, A Jinja2 compliant text string.
    data: dict, A dict of values that will be resolved with the given "template"
  Return:
    success: bool, True if the resolution was successful. False if there where
      any errors in the resolution attempt.
    result: str|dict, If success is true, then the result will be a string
      containing the resutls of resolving the given template with the given
      data.  If success is false, the result will be a dictionary
      representation of the type ResolutionFailure.
  """
  #TODO(raul): Implement error handling logic.

  jinja_template = jinja2.Template(template)
  output = jinja_template.render(data)

  return output
